import msgs, settings, hashlib, hmac, sys, logger, socket, commands

def validate(conn, data):
        if len(data) > 512 or len(data) == 0:
                return msgs.D_INVALID_DATA

        return msgs.D_VALID_DATA


def auth(conn, data, servKey, userKeysFile):
	auth = 1
        ip = conn.getpeername()[0]
        ucrt = hmac.new(servKey)

        ucrt.update(ip)
        inter = ucrt.hexdigest()

        # have to find a way to get user from server here
	fd = open(userKeysFile, "r")
	
	keys = fd.read()

	keysList = keys.split("\r\n")

	for userHash in keysList:
		ih = hmac.new("%s" % (userHash))
		ih.update(inter)
		newdata = ih.hexdigest()
	
		dataComp = data.split("\r\n")[1].rstrip("\r\n")

        	if newdata == dataComp:
			auth = 0
			break
	return auth

def handleData(conn, data, servKey, userKeysFile):
        clnt = str(conn.getpeername()[0])
        port = str(conn.getpeername()[1])
        clnt_context = "%s:%s" % (clnt, port)

        dataLines = data.split("\r\n")

        fn = dataLines[0]
        log.write("%s request from %s" % (fn, clnt_context), 0)
        try:
                func = globals()["%s" % (settings.fns[fn])]
                result = func(conn, data, servKey, userKeysFile)
        except KeyError:
                log.write("invalid auth request from %s" % (clnt_context), 1)
	
	return result

def getData(conn):
        clnt = str(conn.getpeername()[0])
        port = str(conn.getpeername()[1])
        clnt_context = "%s:%s" % (clnt, port)
        data = ""
        valid = msgs.D_VALID_DATA
        while (1):
                conn_data = conn.recv(1024)
                data += str(conn_data)

                if not conn_data:
                        break
                log.write("valdating data from %s" % (clnt_context), 0)

                valid = validate(conn_data, data)

                if valid == msgs.D_INVALID_DATA:
                        break

        if (data and (valid == msgs.D_VALID_DATA)):
                return data
        else:
                return None


log = logger.log(settings.authLogFile)

fd = open("/root/.serverKey", "r")

servKey = fd.read()
servKey = servKey.rstrip("\n")
serv_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
serv_sock.bind(("", 5024))
serv_sock.listen(10)

while (1):
        conn, addr = serv_sock.accept()
        clnt = str(conn.getpeername()[0])
        port = str(conn.getpeername()[1])
        clnt_context = "%s:%s" % (str(clnt), str(port))
        log.write("connection from %s:%s" %(clnt, port), 0)

        data = getData(conn)
        if not data:
                conn.send(msgs.E_INVALID_DATA)

	userKeysFile = "/root/.userKeys"
        result = handleData(conn, data, servKey, userKeysFile)

	if result == 0:
		log.write("user authenticated successfully from %s:%s" % (clnt, port), 0)
		command = data.split("\r\n")[2].rstrip("\r\n")
		output = commands.getoutput(command)
                conn.setblocking(0)
                while (1):
                        try:
                                sent = conn.send(output + "\r\n")
                        except:
                                continue
                        break
                conn.setblocking(1)
		break
	else:
		log.write("user authentication failed from %s:%s" % (clnt, port), 0)
		conn.send("authentication failed")
		break	
	


